package com.ly.config;

import com.ly.security.AuthFilter;
import com.ly.security.AuthProvider;
import com.ly.security.LoginAuthFailHandler;
import com.ly.security.LoginUrlEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
 * @author ：LY
 * @date ：Created in 2020/11/8 17:48
 * @modified By：
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * http权限控制
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.addFilterBefore(authFilter(), UsernamePasswordAuthenticationFilter.class);
        //资源访问权限
       http.authorizeRequests()
               .antMatchers("/admin/login").permitAll()//管理员登录入口
               .antMatchers("/static/**").permitAll()//静态资源]
               .antMatchers("/admin/users").permitAll()
               .antMatchers("/user/login").permitAll()//用户登录入口
               .antMatchers("/admin/**").hasRole("ADMIN")//访问admin文件夹下的资源时必须是ADMIN(管理员)角色状态
               .antMatchers("/user/**").hasAnyRole("ADMIN","USER")//判断访问此路径的用户的角色，不是ADMIN或者USER其中一种则返回false
               .antMatchers("/api/user/**").hasAnyRole("ADMIN","USER")
               .and()
               .formLogin()
               .loginProcessingUrl("/login")//配置角色登录处理入口
               .failureHandler(authFailHandler())//登录失败处理
               .and()
               .logout()
               .logoutUrl("/logout")
               .logoutSuccessUrl("/logout/page")//注销
               .deleteCookies("JSESSIONID")
               .invalidateHttpSession(true)
               .and()
               .exceptionHandling()//配置角色登录控制器
               .authenticationEntryPoint(urlEntryPoint())//默认为/user/login
               .accessDeniedPage("/403");

       http.csrf().disable();
       http.headers().frameOptions().sameOrigin();
    }

    /**
     *  只能有一个AuthenticationManagerBuilder注入
     *  自定认证策略
     * @param auth
     */
    @Autowired
    public void configGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider()).eraseCredentials(true);
    }

    @Bean
    public AuthProvider authProvider() {
        return new AuthProvider();
    }

    @Bean
    public LoginUrlEntryPoint urlEntryPoint(){

        return new LoginUrlEntryPoint("/user/login");
    }
    @Bean
    public LoginAuthFailHandler authFailHandler(){
        return  new LoginAuthFailHandler(urlEntryPoint());
    }

    @Bean
    public AuthenticationManager authenticationManager(){
        AuthenticationManager authenticationManager = null;
        try {
            authenticationManager = super.authenticationManager();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return authenticationManager;
    }

    @Bean
    public AuthFilter authFilter(){
        AuthFilter authFilter = new AuthFilter();
        authFilter.setAuthenticationManager(authenticationManager());
        //验证失败
        authFilter.setAuthenticationFailureHandler(authFailHandler());
        return authFilter;
    }
}
